package com.icongyou.enterprise.talent_pool.service.impl;

import com.icongyou.enterprise.data_aggregation.entity.UserEntity;
import com.icongyou.enterprise.data_aggregation.service.DataAggregationService;
import com.icongyou.enterprise.talent_pool.entity.StudentAssignmentPerformanceEntity;
import com.icongyou.enterprise.talent_pool.entity.dto.TalentDemandDTO;
import com.icongyou.enterprise.talent_pool.entity.vo.*;
import com.icongyou.enterprise.talent_pool.mapper.AssignmentTagMapper;
import com.icongyou.enterprise.talent_pool.mapper.StudentAssignmentPerformanceMapper;
import com.icongyou.enterprise.talent_pool.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class TalentPoolServiceImpl implements TalentPoolService {

    private final TagProcessingService tagProcessingService;
    private final AIModelService aiModelService;
    private final AssignmentTagMapper assignmentTagMapper;
    private final StudentAssignmentPerformanceMapper studentAssignmentPerformanceMapper;
    private final StudentAssignmentPerformanceService studentAssignmentPerformanceService;
    private final DataAggregationService dataAggregationService;
    private final TalentSearchHistoryService talentSearchHistoryService;
    private final CoreCompetenceService coreCompetenceService;

    @Lazy
    @Autowired
    private TalentPoolService selfProxy;

    // 添加搜索结果缓存（参考旧代码）
    private final Map<String, CoreCompetenceResultVO> competenceCache = new ConcurrentHashMap<>();
    private final AtomicLong searchIdCounter = new AtomicLong(0);

    @Override
    public TalentMatchResultVO matchStudentsByDemand(TalentDemandDTO demandDTO) {

        // 保存搜索历史记录
        if (demandDTO.getUserId() != null && demandDTO.getDemandText() != null
                && !demandDTO.getDemandText().trim().isEmpty()) {
            try {
                talentSearchHistoryService.saveSearchHistory(demandDTO.getUserId(), demandDTO.getDemandText());
            } catch (Exception e) {
            }
        }

        // 第一步：提取标签
        List<String> tagIds = extractTagsFromDemand(demandDTO.getDemandText());
        if (tagIds.isEmpty()) {
            return buildEmptyResult(demandDTO);
        }


        // 第三步：根据标签找到相关任务
        List<AssignmentTagVO> relevantAssignments = findRelevantAssignmentsByTags(tagIds);
        if (relevantAssignments.isEmpty()) {
            return buildEmptyResult(demandDTO);
        }


        // 第四步：通过任务找到学生表现数据
        Map<String, List<AssignmentPerformanceVO>> studentPerformances =
                findStudentPerformancesByAssignments(relevantAssignments);

        if (studentPerformances.isEmpty()) {
            return buildEmptyResult(demandDTO);
        }


        // 第六步：计算学生匹配分数并构建StudentTalentVO列表
        List<StudentTalentVO> allScoredStudents = calculateStudentMatchScores(
                studentPerformances, relevantAssignments, demandDTO);

        // 第七步：排序
        allScoredStudents.sort((a, b) -> Double.compare(b.getMatchScore(), a.getMatchScore()));

        // 分页处理（参考StudentTalentService的方式）
        int page = demandDTO.getPage() != null ? demandDTO.getPage() : 1;
        int size = demandDTO.getSize() != null ? demandDTO.getSize() : 10;
        int startIndex = (page - 1) * size;
        int endIndex = Math.min(startIndex + size, allScoredStudents.size());

        List<StudentTalentVO> pagedStudents = allScoredStudents.subList(startIndex, endIndex);

        // 生成搜索ID
        String searchId = generateSearchId();

        // 关键修改：通过代理调用异步方法
        if (demandDTO.getDemandText() != null && !demandDTO.getDemandText().trim().isEmpty()) {
            // 使用代理调用，确保异步生效
            selfProxy.generateCoreCompetenceLabelAsync(demandDTO, pagedStudents, searchId,
                    relevantAssignments, studentPerformances);
        } else {
            // 直接设置为完成状态
            CoreCompetenceResultVO result = new CoreCompetenceResultVO();
            result.setSearchId(searchId);
            result.setStatus("COMPLETED");
            result.setCompetenceLabels(Collections.emptyMap());
            competenceCache.put(searchId, result);
        }

        // 构建返回结果
        TalentMatchResultVO result = new TalentMatchResultVO();
        result.setMatchedStudents(pagedStudents);
        result.setExtractedTags(Collections.emptyMap()); // 暂时为空，后续可根据需要填充
        result.setCurrentPage(page);
        result.setPageSize(size);
        result.setTotalCount(allScoredStudents.size());
        result.setHasMore(endIndex < allScoredStudents.size());
        result.setSearchId(searchId);

        return result;
    }

    /**
     * 构建空结果
     */
    private TalentMatchResultVO buildEmptyResult(TalentDemandDTO demandDTO) {
        TalentMatchResultVO result = new TalentMatchResultVO();
        result.setMatchedStudents(Collections.emptyList());
        result.setExtractedTags(Collections.emptyMap());
        result.setCurrentPage(demandDTO.getPage() != null ? demandDTO.getPage() : 1);
        result.setPageSize(demandDTO.getSize() != null ? demandDTO.getSize() : 10);
        result.setTotalCount(0);
        result.setHasMore(false);
        result.setSearchId(generateSearchId());
        return result;
    }

    /**
     * 从需求文本中提取标签
     */
    public List<String> extractTagsFromDemand(String demandText) {
        if (demandText == null || demandText.trim().isEmpty()) {
            return Collections.emptyList();
        }


        // 使用大模型分析需求文本，提取标签和近似标签（不需要关联度）
        List<TagDemandAnalysisResult> tagAnalysisResults = aiModelService.analyzeDemandTags(demandText);

        List<String> processedTagIds = new ArrayList<>();

        for (TagDemandAnalysisResult result : tagAnalysisResults) {
            String tagName = result.getTagName();
            List<String> similarTags = result.getSimilarTags();


            // 处理标签（包括对有、有近似、无近似三种情况的处理，比如实时计算任务-标签关联等）
            String tagId = tagProcessingService.processGeneratedTag(tagName, similarTags);
            if (tagId != null) {
                processedTagIds.add(tagId);
            } else {
            }
        }

        return processedTagIds;
    }

    /**
     * 第三步：根据需求标签找到相关任务
     */
    private List<AssignmentTagVO> findRelevantAssignmentsByTags(List<String> tagIds) {

        List<AssignmentTagVO> allAssignmentTags = new ArrayList<>();
        for (String tagId : tagIds) {
            List<AssignmentTagVO> tagAssignments = assignmentTagMapper.getAssignmentTagVOsByTagId(tagId);
            allAssignmentTags.addAll(tagAssignments);
        }

        if (allAssignmentTags.isEmpty()) {
            return Collections.emptyList();
        }

        // 按assignmentId分组，计算累加综合得分
        Map<String, AssignmentTagVO> assignmentMap = new HashMap<>();
        Map<String, BigDecimal> accumulatedScores = new HashMap<>(); // 存储累加得分

        for (AssignmentTagVO assignmentTagVO : allAssignmentTags) {
            String assignmentId = assignmentTagVO.getAssignmentId();
            BigDecimal compositeScore = assignmentTagVO.getRelevance().multiply(assignmentTagVO.getAssignmentWeight());

            if (assignmentMap.containsKey(assignmentId)) {
                // 如果任务已存在，累加新来的compositeScore乘以0.5
                BigDecimal existingAccumulatedScore = accumulatedScores.get(assignmentId);
                BigDecimal newAccumulatedScore = existingAccumulatedScore.add(compositeScore.multiply(new BigDecimal("0.5")));
                accumulatedScores.put(assignmentId, newAccumulatedScore);

                // 更新对应的AssignmentTagVO的relevance为累加后的得分（标准化处理）
                // 这里我们保持原有的relevance和assignmentWeight不变，只在排序时使用累加得分
            } else {
                // 第一次出现，直接放入
                assignmentMap.put(assignmentId, assignmentTagVO);
                accumulatedScores.put(assignmentId, compositeScore);
            }
        }

        // 按累加综合得分排序，选择top 3-5个任务
        return assignmentMap.values().stream()
                .sorted((a, b) -> {
                    BigDecimal scoreA = accumulatedScores.get(a.getAssignmentId());
                    BigDecimal scoreB = accumulatedScores.get(b.getAssignmentId());
                    return scoreB.compareTo(scoreA);
                })
                .limit(5)
                .collect(Collectors.toList());
    }

    /**
     * 第四步：通过任务找到学生表现数据
     */
    private Map<String, List<AssignmentPerformanceVO>> findStudentPerformancesByAssignments(
            List<AssignmentTagVO> assignments) {

        Map<String, List<AssignmentPerformanceVO>> studentPerformances = new HashMap<>();
        List<String> assignmentIds = assignments.stream()
                .map(AssignmentTagVO::getAssignmentId)
                .collect(Collectors.toList());

        // 批量获取所有任务的表现数据
        List<StudentAssignmentPerformanceEntity> allPerformances =
                studentAssignmentPerformanceMapper.getPerformancesByAssignmentIds(assignmentIds);

        // 构建任务映射，便于查找任务信息
        Map<String, AssignmentTagVO> assignmentMap = assignments.stream()
                .collect(Collectors.toMap(AssignmentTagVO::getAssignmentId, a -> a));

        // 检查是否有缺失的表现数据
        Set<String> assignmentsWithData = allPerformances.stream()
                .map(StudentAssignmentPerformanceEntity::getAssignmentId)
                .collect(Collectors.toSet());

        List<String> assignmentsWithoutData = assignmentIds.stream()
                .filter(id -> !assignmentsWithData.contains(id))
                .collect(Collectors.toList());

        // 实时计算缺失的表现数据
        if (!assignmentsWithoutData.isEmpty()) {
            for (String assignmentId : assignmentsWithoutData) {
                try {
                    List<StudentAssignmentPerformanceEntity> realtimePerformances =
                            studentAssignmentPerformanceService.calculateAssignmentPerformanceRealtime(assignmentId);
                    if (!realtimePerformances.isEmpty()) {
                        studentAssignmentPerformanceMapper.batchInsertStudentAssignmentPerformance(realtimePerformances);
                        allPerformances.addAll(realtimePerformances);
                    }
                } catch (Exception e) {
                }
            }
        }

        // 组织数据结构
        for (StudentAssignmentPerformanceEntity performance : allPerformances) {
            String assignmentId = performance.getAssignmentId();
            AssignmentTagVO assignmentInfo = assignmentMap.get(assignmentId);
            if (assignmentInfo != null) {
                AssignmentPerformanceVO performanceVO = new AssignmentPerformanceVO();
                performanceVO.setAssignmentId(assignmentId);
                performanceVO.setAssignmentName(assignmentInfo.getAssignmentName());
                performanceVO.setPerformanceScore(BigDecimal.valueOf(performance.getPerformanceScore()));
                performanceVO.setRelevance(assignmentInfo.getRelevance());
                performanceVO.setAssignmentWeight(assignmentInfo.getAssignmentWeight());

                String studentId = performance.getStudentId();
                studentPerformances
                        .computeIfAbsent(studentId, k -> new ArrayList<>())
                        .add(performanceVO);
            }
        }

        return studentPerformances;
    }

    /**
     * 第六步：计算学生匹配分数并构建StudentTalentVO
     */
    private List<StudentTalentVO> calculateStudentMatchScores(
            Map<String, List<AssignmentPerformanceVO>> studentPerformances,
            List<AssignmentTagVO> relevantAssignments,
            TalentDemandDTO demandDTO) {

        List<StudentTalentVO> results = new ArrayList<>();

        for (Map.Entry<String, List<AssignmentPerformanceVO>> entry : studentPerformances.entrySet()) {
            String studentId = entry.getKey();
            List<AssignmentPerformanceVO> performances = entry.getValue();

            // 检查筛选条件
            if (!passFilters(studentId, demandDTO)) {
                continue;
            }

            // 获取学生基本信息并构建StudentTalentVO
            StudentTalentVO studentTalent = convertToStudentTalentVO(studentId, performances);
            if (studentTalent == null) {
                continue;
            }

            // 计算匹配分数
            double matchScore = calculateMatchScore(performances);
            studentTalent.setMatchScore(matchScore);

            results.add(studentTalent);
        }

        return results;
    }

    /**
     * 检查筛选条件（参考旧代码）
     */
    private boolean passFilters(String studentId, TalentDemandDTO demandDTO) {
        // 教师推荐条件
        if (demandDTO.getTeacherRecommended() != null && demandDTO.getTeacherRecommended()) {
            Boolean isRecommended = dataAggregationService.isTeacherRecommended(studentId);
            if (isRecommended == null || !isRecommended) {
                return false;
            }
        }

        // 核心任务top 30%条件
        if (demandDTO.getCoreTaskTop30() != null && demandDTO.getCoreTaskTop30()) {
            Boolean isTop30 = dataAggregationService.isCoreTaskTop30(studentId);
            if (isTop30 == null || !isTop30) {
                return false;
            }
        }

        // 高潜力成果条件
        if (demandDTO.getHasHighPotential() != null && demandDTO.getHasHighPotential()) {
            Boolean hasHighPotential = dataAggregationService.hasHighPotentialSubmission(studentId);
            if (hasHighPotential == null || !hasHighPotential) {
                return false;
            }
        }

        return true;
    }

    /**
     * 将学生转换为StudentTalentVO（修改后的版本）
     */
    private StudentTalentVO convertToStudentTalentVO(String studentId,
                                                     List<AssignmentPerformanceVO> performances) {
        UserEntity userEntity = dataAggregationService.getStudentById(studentId);
        if (userEntity == null) {
            return null;
        }

        StudentTalentVO vo = new StudentTalentVO();
        vo.setStudentId(studentId);
        vo.setRealName(userEntity.getRealName());
        vo.setAvatar(userEntity.getAvatar());
        vo.setMajor(userEntity.getMajor());
        vo.setRanking(userEntity.getRanking());

        // 获取学校名称（通过租户ID）
        String school = dataAggregationService.getTenantNameByUserId(studentId);
        vo.setSchool(school);

        // 获取同专业总人数
        Integer totalMajorStudents = dataAggregationService.countStudentsByMajor(
                userEntity.getTenantId(), userEntity.getMajor());
        vo.setTotalMajorStudents(totalMajorStudents != null ? totalMajorStudents : 0);

        // 新的核心成果获取逻辑：从performanceScore最高的任务中获取
        CoreSubmissionVO coreSubmission = getCoreSubmissionFromPerformances(studentId, performances);
        vo.setCoreSubmission(coreSubmission);

        return vo;
    }

    /**
     * 从学生表现数据中获取核心成果
     */
    private CoreSubmissionVO getCoreSubmissionFromPerformances(String studentId,
                                                               List<AssignmentPerformanceVO> performances) {
        if (performances == null || performances.isEmpty()) {
            // 如果没有表现数据，回退到原来的方法
            return dataAggregationService.getCoreSubmission(studentId);
        }

        try {
            // 找到performanceScore最高的任务
            AssignmentPerformanceVO bestPerformance = performances.stream()
                    .max(Comparator.comparing(p -> p.getPerformanceScore().doubleValue()))
                    .orElse(null);

            if (bestPerformance != null) {
                // 使用新方法获取该任务的核心成果
                CoreSubmissionVO coreSubmission = dataAggregationService
                        .getCoreSubmissionByAssignmentId(studentId, bestPerformance.getAssignmentId());

                if (coreSubmission != null) {
                    return coreSubmission;
                }
            }

            // 如果通过新方法没找到，回退到原来的方法
            return dataAggregationService.getCoreSubmission(studentId);

        } catch (Exception e) {
            log.error("从表现数据获取核心成果失败, studentId: {}", studentId, e);
            // 出错时回退到原来的方法
            return dataAggregationService.getCoreSubmission(studentId);
        }
    }

    /**
     * 计算匹配分数
     * 公式：Σ(关联度 × 任务重要性权重 × 学生表现得分) / 任务数量
     */
    private double calculateMatchScore(List<AssignmentPerformanceVO> performances) {
        if (performances.isEmpty()) {
            return 0.0;
        }

        double totalScore = 0.0;

        for (AssignmentPerformanceVO performance : performances) {
            // 关联度 × 任务重要性权重 × 学生表现得分（归一化到0-1）
            double normalizedPerformance = performance.getPerformanceScore().doubleValue() / 100.0;
            double assignmentScore = performance.getRelevance().doubleValue()
                    * performance.getAssignmentWeight().doubleValue()
                    * normalizedPerformance;

            totalScore += assignmentScore;
        }

        // 平均分数
        return totalScore / performances.size();
    }

    // 指定使用自定义的线程池
    @Async("taskExecutor")
    public void generateCoreCompetenceLabelAsync(TalentDemandDTO demandDTO,
                                                 List<StudentTalentVO> matchedStudents,
                                                 String searchId,
                                                 List<AssignmentTagVO> relevantAssignments,
                                                 Map<String, List<AssignmentPerformanceVO>> studentPerformances) {

        try {
            // 初始化缓存状态
            CoreCompetenceResultVO cacheResult = new CoreCompetenceResultVO();
            cacheResult.setSearchId(searchId);
            cacheResult.setStatus("PROCESSING");
            cacheResult.setMessage("核心竞争力标签生成中...");
            competenceCache.put(searchId, cacheResult);

            // 调用大模型生成核心竞争力标签
            Map<String, String> competenceLabels = new HashMap<>();

            for (StudentTalentVO student : matchedStudents) {
                try {
                    // 获取该学生的表现数据
                    List<AssignmentPerformanceVO> studentPerformanceList =
                            studentPerformances.getOrDefault(student.getStudentId(), Collections.emptyList());

                    String coreCompetenceLabel = coreCompetenceService.generateCoreCompetenceLabel(
                            demandDTO.getDemandText(),
                            student.getStudentId(),
                            relevantAssignments,
                            studentPerformanceList
                    );
                    competenceLabels.put(student.getStudentId(), coreCompetenceLabel);

                    // 添加小延迟避免过于频繁调用
                    Thread.sleep(100);
                } catch (Exception e) {
                    competenceLabels.put(student.getStudentId(), "能力评估生成中...");
                }
            }

            // 更新缓存
            CoreCompetenceResultVO completedResult = new CoreCompetenceResultVO();
            completedResult.setSearchId(searchId);
            completedResult.setStatus("COMPLETED");
            completedResult.setCompetenceLabels(competenceLabels);
            completedResult.setMessage("核心竞争力标签生成完成");
            competenceCache.put(searchId, completedResult);

        } catch (Exception e) {

            // 更新缓存为失败状态
            CoreCompetenceResultVO failedResult = new CoreCompetenceResultVO();
            failedResult.setSearchId(searchId);
            failedResult.setStatus("FAILED");
            failedResult.setMessage("核心竞争力标签生成失败: " + e.getMessage());
            competenceCache.put(searchId, failedResult);
        }
    }

    /**
     * 查询核心竞争力label生成结果
     */
    @Override
    public CoreCompetenceResultVO getCoreCompetenceResult(String searchId) {
        CoreCompetenceResultVO result = competenceCache.get(searchId);
        if (result == null) {
            result = new CoreCompetenceResultVO();
            result.setSearchId(searchId);
            result.setStatus("NOT_FOUND");
            result.setMessage("未找到对应的搜索结果");
        }
        return result;
    }

    /**
     * 生成搜索ID（参考旧代码）
     */
    private String generateSearchId() {
        return "search_" + System.currentTimeMillis() + "_" + searchIdCounter.incrementAndGet();
    }
}